using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DragonAwakening.Game;
using Microsoft.Xna.Framework;

namespace DragonAwakening.Core.World
{
    /// <summary>
    /// Map cells processor.
    /// </summary>
    public class WorldMapCellsProcessor : WorldDataProcessor
    {
        /// <summary>
        /// Creates the processor.
        /// </summary>
        public WorldMapCellsProcessor(IWorldDataProcessor next, IWorld world)
            : base(next, world)
        { 
        }

        /// <summary>
        /// Process the data.
        /// </summary>
        public override void Process(string data, int index)
        {
            var worldSize = this.world.Size;

            for (int yCoordinate = 0; yCoordinate < worldSize.Y; yCoordinate++)
            for (int xCoordinate = 0; xCoordinate < worldSize.X; xCoordinate++)
            {
                string chunk;
                index = this.TryReadDataChunk(data, index, out chunk);
                if (index == -1)
                {
                    // [LOG] Error: Map cell count / dimentions don't match to the number of map cells in the stream.
                    return;
                }

                if (string.IsNullOrEmpty(chunk))
                {
                    continue;
                }

                int chunkLength = chunk.Length;
                if (chunk[0] == '{' && chunk[chunkLength - 1] == '}' && (chunkLength == 6 || (chunkLength > 6 && (chunkLength - 6) % 2 == 0)))
                {
                    int north = chunk[1] - '0', east = chunk[2] - '0', south = chunk[3] - '0', west = chunk[4] - '0', floor = chunk[5] - '0', sky = chunk[6] - '0';
                    byte[] creatures = null;

                    if (chunkLength > 6)
                    {
                        int creaturesCount = (chunkLength - 8) / 2;
                        creatures = new byte[creaturesCount];
                        for (int creatureIndex = 0; creatureIndex < creaturesCount; creatureIndex++)
                        {
                            char highBit = chunk[7 + creatureIndex*2];
                            char lowBit = chunk[8 + creatureIndex*2];

                            int highValue = highBit >= 'A' ? highBit - 'A' + 10 : highBit - '0';
                            int lowValue = lowBit >= 'A' ? lowBit - 'A' + 10 : lowBit - '0';

                            creatures[creatureIndex] = (byte)(highValue * 16 + lowValue);
                        }
                    }

                    var cell = new MapCell(xCoordinate, yCoordinate, (byte)north, (byte)south, (byte)east, (byte)west, (byte)floor, (byte)sky, creatures);
                    this.world.SetCell(cell, new Point(xCoordinate, yCoordinate));
                }
                else
                { 
                    // [LOG] Warning: Map cell at index {index} is malformed. Skipping.
                }
            }
        }
    }
}

